home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONX_FO / OARITH.C < prev    next >
Text File  |  1990-03-02  |  18KB  |  853 lines

  1. /*
  2.  * File: oarith.c
  3.  *  Contents: divide, minus, mod, mult, neg, number, plus, powr
  4.  */
  5.  
  6. #include <math.h>
  7. #include "::h:config.h"
  8. #include "::h:rt.h"
  9. #include "rproto.h"
  10.  
  11. #ifdef PreProcess
  12. /* include(../M4/ops.m4) /* */
  13. /* */
  14. #endif                    /* PreProcess */
  15.  
  16. #ifdef SUN
  17. #include <signal.h>
  18. #endif                    /* SUN */
  19.  
  20. int over_flow;
  21.  
  22. /*
  23.  * x / y - divide y into x.
  24.  */
  25.  
  26. OpDcl(divide,2,"/")
  27.    {
  28.    register int t1, t2;
  29.    double r1, r2;
  30.  
  31.    /*
  32.     * Arg1 and Arg2 must be numeric.
  33.     */
  34.    if ((t1 = cvnum(&Arg1)) == CvtFail)
  35.       RunErr(102, &Arg1);
  36.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  37.       RunErr(102, &Arg2);
  38.  
  39.    if (t1 == T_Integer && t2 == T_Integer) {
  40.       /*
  41.        * Arg1 and Arg2 are both integers, just divide them and return the
  42.        * result.
  43.        */
  44.       if (IntVal(Arg2) == 0L) 
  45.          RunErr(201, &Arg2);
  46.  
  47. #if MSDOS && LATTICE
  48.       {
  49.       long i, j;
  50.       i = IntVal(Arg1);
  51.       j = i / IntVal(Arg2);
  52.       MakeInt(j, &Arg0);
  53.       }
  54. #else                    /* MSDOS && LATTICE */
  55.        MakeInt(IntVal(Arg1) / IntVal(Arg2), &Arg0);
  56. #endif                    /* MSDOS && LATTICE */
  57.  
  58.       }
  59.    else if (t1 == T_Real || t2 == T_Real) {
  60.       /*
  61.        * Either Arg1 or Arg2 or both is real, convert the real values to
  62.        *  integers, divide them, and return the result.
  63.        */
  64.       if (t1 != T_Real) {
  65.  
  66. #ifdef LargeInts
  67.          if (t1 == T_Bignum)
  68.         r1 = bigtoreal(&Arg1);
  69.      else
  70. #endif                    /* LargeInts */
  71.  
  72. #ifdef WATERLOO_C_V3_0
  73.             {
  74.         long int l;
  75.             double d;
  76.  
  77.             d = IntVal(Arg1);
  78.             r1 = d;
  79.             }
  80. #else                    /* WATERLOO_C_V3_0 */
  81.             r1 = IntVal(Arg1);
  82. #endif                    /* WATERLOO_C_V3_0 */
  83.          }
  84.       else
  85.      r1 = BlkLoc(Arg1)->realblk.realval;
  86.  
  87.       if (t2 != T_Real) {
  88.  
  89. #ifdef LargeInts
  90.      if (t2 == T_Bignum)
  91.         r2 = bigtoreal(&Arg2);
  92.      else
  93. #endif                    /* LargeInts */
  94.  
  95. #ifdef WATERLOO_C_V3_0
  96.             {
  97.         long int l;
  98.             double d;
  99.  
  100.             d = IntVal(Arg2);
  101.             r2 = d;
  102.             }
  103. #else                    /* WATERLOO_C_V3_0 */
  104.             r2 = IntVal(Arg2);
  105. #endif                    /* WATERLOO_C_V3_0 */
  106.  
  107.          }
  108.       else
  109.      r2 = BlkLoc(Arg2)->realblk.realval;
  110.  
  111.       if (r2 == 0.0) 
  112.          RunErr(-204, NULL);
  113.  
  114.       if (makereal(r1 / r2, &Arg0) == Error) 
  115.          RunErr(0, NULL);
  116.  
  117. #ifdef SUN
  118.       if (((struct b_real *)BlkLoc(Arg0))->realval == HUGE)
  119.          kill(getpid(),SIGFPE);
  120. #endif                    /* SUN */
  121.  
  122.       }
  123.  
  124. #ifdef LargeInts
  125.    else {
  126.       /*
  127.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  128.        */
  129.       if (bigdiv(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  130.      RunErr(0, NULL);
  131.       }
  132. #endif                    /* LargeInts */
  133.  
  134.    Return;
  135.    }
  136.  
  137.  
  138. /*
  139.  * x - y - subtract y from x.
  140.  */
  141.  
  142. OpDcl(minus,2,"-")
  143.    {
  144.    register int t1, t2;
  145.    double r1, r2;
  146.  
  147.    /*
  148.     * x and y must be numeric.  Save the cvnum return values for later use.
  149.     */
  150.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  151.       RunErr(102, &Arg1);
  152.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  153.       RunErr(102, &Arg2);
  154.  
  155.    if (t1 == T_Integer && t2 == T_Integer) {
  156.       /*
  157.        * Both x and y are integers.  Perform integer subtraction and place
  158.        *  the result in Arg0 as the return value.
  159.        */
  160.  
  161.       MakeInt(sub(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  162.       if (over_flow)
  163.  
  164. #ifdef LargeInts
  165.      if (bigsub(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  166.         RunErr(0, NULL);
  167. #else                    /* LargeInts */
  168.          RunErr(-203, NULL);
  169. #endif                    /* LargeInts */
  170.  
  171.       }
  172.    else if (t1 == T_Real || t2 == T_Real) {
  173.       /*
  174.        * Either x or y is real, convert the other to a real, perform
  175.        *  the subtraction and place the result in Arg0 as the return value.
  176.        */
  177.       if (t1 != T_Real) {
  178.  
  179. #ifdef LargeInts
  180.          if (t1 == T_Bignum)
  181.         r1 = bigtoreal(&Arg1);
  182.      else
  183. #endif                    /* LargeInts */
  184.  
  185. #ifdef WATERLOO_C_V3_0
  186.             {
  187.         long int l;
  188.             double d;
  189.  
  190.             d = IntVal(Arg1);
  191.             r1 = d;
  192.             }
  193. #else                    /* WATERLOO_C_V3_0 */
  194.             r1 = IntVal(Arg1);
  195. #endif                    /* WATERLOO_C_V3_0 */
  196.          }
  197.       else
  198.      r1 = BlkLoc(Arg1)->realblk.realval;
  199.  
  200.       if (t2 != T_Real) {
  201.  
  202. #ifdef LargeInts
  203.      if (t2 == T_Bignum)
  204.         r2 = bigtoreal(&Arg2);
  205.      else
  206. #endif                    /* LargeInts */
  207.  
  208. #ifdef WATERLOO_C_V3_0
  209.             {
  210.         long int l;
  211.             double d;
  212.  
  213.             d = IntVal(Arg2);
  214.             r2 = d;
  215.             }
  216. #else                    /* WATERLOO_C_V3_0 */
  217.             r2 = IntVal(Arg2);
  218. #endif                    /* WATERLOO_C_V3_0 */
  219.          }
  220.       else
  221.      r2 = BlkLoc(Arg2)->realblk.realval;
  222.  
  223. #ifdef  RTACIS
  224.       {
  225.       double rtbug_temporary;    /* bug with "-" arithmetic as parameter */
  226.       rtbug_temporary = r1 - r2;    
  227.       if (makereal(rtbug_temporary, &Arg0) == Error) 
  228.          RunErr(0, NULL);
  229. #else                    /* RTACIS */
  230.       if (makereal(r1 - r2, &Arg0) == Error) 
  231.          RunErr(0, NULL);
  232. #endif                    /* RTACIS */
  233.  
  234.       }
  235.  
  236. #ifdef LargeInts
  237.    else {
  238.       /*
  239.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  240.        */
  241.       if (bigsub(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  242.      RunErr(0, NULL);
  243.       }
  244. #endif                    /* LargeInts */
  245.  
  246.    Return;
  247.    }
  248.  
  249.  
  250. /*
  251.  * x % y - take remainder of x / y.
  252.  */
  253.  
  254. OpDcl(mod,2,"%")
  255.    {
  256.    register int t1, t2;
  257.    long int_rslt;
  258.    double r1, r2, real_rslt;
  259.  
  260.    /*
  261.     * x and y must be numeric.  Save the cvnum return values for later use.
  262.     */
  263.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  264.       RunErr(102, &Arg1);
  265.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  266.       RunErr(102, &Arg2);
  267.  
  268.    if (t1 == T_Integer && t2 == T_Integer) {
  269.       /*
  270.        * Both x and y are integers.  If y is 0, generate an error because
  271.        *  it's divide by 0.  Otherwise, just return the modulus of the
  272.        *  two arguments.
  273.        */
  274.       if (IntVal(Arg2) == 0L) 
  275.          RunErr(202, &Arg2);
  276.  
  277. #if MSDOS && LATTICE
  278.       {
  279.       long i;
  280.       i = IntVal(Arg1);
  281.       int_rslt = i % IntVal(Arg2);
  282.       }
  283. #else                    /* MSDOS && LATTICE */
  284.        int_rslt = IntVal(Arg1) % IntVal(Arg2);
  285. #endif                    /* MSDOS && LATTICE */
  286.  
  287.       /*
  288.        * The sign of the result must match that of n1.
  289.        */
  290.       if (IntVal(Arg1) < 0) {
  291.          if (int_rslt > 0)
  292.             int_rslt -= Abs(IntVal(Arg2));
  293.          }
  294.       else if (int_rslt < 0)
  295.          int_rslt += Abs(IntVal(Arg2));
  296.       MakeInt(int_rslt, &Arg0);
  297.       }
  298.    else if (t1 == T_Real || t2 == T_Real) {
  299.       /*
  300.        * Either x or y is real, convert the other to a real, get
  301.        *  the modulus, convert the result to an integer and place it
  302.        *  in Arg0 as the return value.
  303.        */
  304.       if (t1 != T_Real) {
  305.  
  306. #ifdef LargeInts
  307.      if (t1 == T_Bignum)
  308.         r1 = bigtoreal(&Arg1);
  309.      else
  310. #endif                    /* LargeInts */
  311.  
  312. #ifdef WATERLOO_C_V3_0
  313.             {
  314.         long int l;
  315.             double d;
  316.  
  317.             d = IntVal(Arg1);
  318.             r1 = d;
  319.             }
  320. #else                    /* WATERLOO_C_V3_0 */
  321.             r1 = IntVal(Arg1);
  322. #endif                    /* WATERLOO_C_V3_0 */
  323.          }
  324.       else
  325.      r1 = BlkLoc(Arg1)->realblk.realval;
  326.  
  327.       if (t2 != T_Real) {
  328.  
  329. #ifdef LargeInts
  330.      if (t2 == T_Bignum)
  331.         r2 = bigtoreal(&Arg2);
  332.      else
  333. #endif                    /* LargeInts */
  334.  
  335. #ifdef WATERLOO_C_V3_0
  336.             {
  337.         long int l;
  338.             double d;
  339.  
  340.             d = IntVal(Arg2);
  341.             r2 = d;
  342.             }
  343. #else                    /* WATERLOO_C_V3_0 */
  344.             r2 = IntVal(Arg2);
  345. #endif                    /* WATERLOO_C_V3_0 */
  346.          }
  347.       else
  348.      r2 = BlkLoc(Arg2)->realblk.realval;
  349.  
  350.       real_rslt = r1 - r2 * (int)(r1 / r2);
  351.       /*
  352.        * The sign of the result must match that of n1.
  353.        */
  354.       if (r1 < 0.0) {
  355.          if (real_rslt > 0.0)
  356.             real_rslt -= fabs(r2);
  357.          }
  358.       else if (real_rslt < 0.0)
  359.          real_rslt += fabs(r2);
  360.       if (makereal(real_rslt, &Arg0) == Error) 
  361.          RunErr(0, NULL);
  362.       }
  363.  
  364. #ifdef LargeInts
  365.    else {
  366.       /*
  367.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  368.        */
  369.       if (bigmod(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  370.      RunErr(0, NULL);
  371.       }
  372. #endif                    /* LargeInts */
  373.  
  374.    Return;
  375.    }
  376.  
  377.  
  378. /*
  379.  * x * y - multiply x and y.
  380.  */
  381.  
  382. OpDcl(mult,2,"*")
  383.    {
  384.    register int t1, t2;
  385.    double r1, r2;
  386.  
  387.    /*
  388.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  389.     *  use.
  390.     */
  391.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  392.       RunErr(102, &Arg1);
  393.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  394.       RunErr(102, &Arg2);
  395.  
  396.    if (t1 == T_Integer && t2 == T_Integer) {
  397.       /*
  398.        * Both Arg1 and Arg2 are integers.  Perform the multiplication and
  399.        *  and place the result in Arg0 as the return value.
  400.        */
  401.  
  402.       MakeInt(mul(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  403.       if (over_flow)
  404. #ifdef LargeInts
  405.      if (bigmul(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  406.         RunErr(0, NULL);
  407. #else                    /* LargeInts */
  408.          RunErr(-203, NULL);
  409. #endif                    /* LargeInts */
  410.       }
  411.    else if (t1 == T_Real || t2 == T_Real) {
  412.       /*
  413.        * Either Arg1 or Arg2 is real, convert the other to a real, perform
  414.        *  the subtraction and place the result in Arg0 as the return value.
  415.        */
  416.       if (t1 != T_Real) {
  417.  
  418. #ifdef LargeInts
  419.      if (t1 == T_Bignum)
  420.         r1 = bigtoreal(&Arg1);
  421.      else
  422. #endif                    /* LargeInts */
  423.  
  424. #ifdef WATERLOO_C_V3_0
  425.             {
  426.         long int l;
  427.             double d;
  428.  
  429.             d = IntVal(Arg1);
  430.             r1 = d;
  431.             }
  432. #else                    /* WATERLOO_C_V3_0 */
  433.             r1 = IntVal(Arg1);
  434. #endif                    /* WATERLOO_C_V3_0 */
  435.          }
  436.       else
  437.      r1 = BlkLoc(Arg1)->realblk.realval;
  438.  
  439.       if (t2 != T_Real) {
  440.  
  441. #ifdef LargeInts
  442.      if (t2 == T_Bignum)
  443.         r2  = bigtoreal(&Arg2);
  444.      else
  445. #endif                    /* LargeInts */
  446.  
  447. #ifdef WATERLOO_C_V3_0
  448.             {
  449.         long int l;
  450.             double d;
  451.  
  452.             d = IntVal(Arg2);
  453.             r2 = d;
  454.             }
  455. #else                    /* WATERLOO_C_V3_0 */
  456.             r2 = IntVal(Arg2);
  457. #endif                    /* WATERLOO_C_V3_0 */
  458.          }
  459.       else
  460.      r2 = BlkLoc(Arg2)->realblk.realval;
  461.  
  462.       if (makereal(r1 * r2, &Arg0) == Error) 
  463.          RunErr(0, NULL);
  464.       }
  465.  
  466. #ifdef LargeInts
  467.    else {
  468.       /*
  469.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  470.        */
  471.       if (bigmul(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  472.      RunErr(0, NULL);
  473.       }
  474. #endif                    /* LargeInts */
  475.  
  476.    Return;
  477.    }
  478.  
  479. /*
  480.  * -x - negate x.
  481.  */
  482.  
  483. OpDcl(neg,1,"-")
  484.    {
  485.  
  486.    /*
  487.     * Arg1 must be numeric.
  488.     */
  489.    switch (cvnum(&Arg1)) {
  490.  
  491.       case T_Integer:
  492.          /*
  493.           * If Arg1 is an integer, check for overflow by negating it and
  494.           *  seeing if the negation didn't "work".  Use MakeInt to
  495.           *  construct the return value.
  496.           */
  497.  
  498.      MakeInt(neg(IntVal(Arg1)), &Arg0);
  499.          if (over_flow)
  500.  
  501. #ifdef LargeInts
  502.         if (bigneg(&Arg1, &Arg0) == Error)  /* alcbignum failed */
  503.            RunErr(0, NULL);
  504. #else                    /* LargeInts */
  505.          RunErr(-203, &Arg1);
  506. #endif                    /* LargeInts */
  507.  
  508.          break;
  509.  
  510. #ifdef LargeInts
  511.       case T_Bignum:
  512.      if (cpbignum(&Arg1, &Arg0) == Error)  /* alcbignum failed */
  513.         RunErr(0, NULL);
  514.      BlkLoc(Arg0)->bignumblk.sign ^= 1;
  515.      break;
  516. #endif                    /* LargeInts */
  517.  
  518.       case T_Real:
  519.          /*
  520.           * Arg1 is real, just negate it and use makereal to construct the
  521.           *  return value.
  522.           */
  523.  
  524. #ifdef RTACIS
  525.          { 
  526.          double rtbug_temporary;        /* bug with "-" as parameter */
  527.          rtbug_temporary = -BlkLoc(Arg1)->realblk.realval;
  528.          if (makereal(rtbug_temporary, &Arg0) == Error) 
  529.             RunErr(0, NULL);
  530.          }
  531. #else                    /* RTACIS */
  532.          if (makereal(-BlkLoc(Arg1)->realblk.realval, &Arg0) == Error) 
  533.             RunErr(0, NULL);
  534. #endif                    /* RTACIS */
  535.  
  536.          break;
  537.  
  538.       default:
  539.          /*
  540.           * Arg1 is not numeric.
  541.           */
  542.          RunErr(102, &Arg1);
  543.       }
  544.    Return;
  545.    }
  546.  
  547. /*
  548.  * +x - convert x to numeric type.
  549.  *  Operational definition: generate runerr if x is not numeric.
  550.  */
  551.  
  552. OpDcl(number,1,"+")
  553.    {
  554.  
  555.    switch (cvnum(&Arg1)) {
  556.  
  557.       case T_Integer:
  558.  
  559. #ifdef LargeInts
  560.       case T_Bignum:
  561. #endif                    /* LargeInts */
  562.  
  563.       case T_Real:
  564.      Arg0 = Arg1;
  565.          break;
  566.  
  567.       default:
  568.          RunErr(102, &Arg1);
  569.       }
  570.    Return;
  571.    }
  572.  
  573. /*
  574.  * x + y - add x and y.
  575.  */
  576.  
  577. OpDcl(plus,2,"+")
  578.    {
  579.    register int t1, t2;
  580.    double r1, r2;
  581.  
  582.    /*
  583.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  584.     *  use.
  585.     */
  586.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  587.       RunErr(102, &Arg1);
  588.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  589.       RunErr(102, &Arg2);
  590.  
  591.    if (t1 == T_Integer && t2 == T_Integer) {
  592.       /*
  593.        * Both Arg1 and Arg2 are integers.  Perform integer addition and plcae
  594.        *  the result in Arg0 as the return value.
  595.        */
  596.  
  597.       MakeInt(add(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  598.       if (over_flow)
  599.  
  600. #ifdef LargeInts
  601.      if (bigadd(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  602.         RunErr(0, NULL);
  603. #else                    /* LargeInts */
  604.          RunErr(-203, NULL);
  605. #endif                    /* LargeInts */
  606.  
  607.       }
  608.    else if (t1 == T_Real || t2 == T_Real) {
  609.       /*
  610.        * Either Arg1 or Arg2 is real, convert the other to a real, perform
  611.        *  the addition and place the result in Arg0 as the return value.
  612.        */
  613.       if (t1 != T_Real) {
  614.  
  615. #ifdef LargeInts
  616.      if (t1 == T_Bignum)
  617.         r1 = bigtoreal(&Arg1);
  618.      else
  619. #endif                    /* LargeInts */
  620.  
  621. #ifdef WATERLOO_C_V3_0
  622.             {
  623.         long int l;
  624.             double d;
  625.  
  626.             d = IntVal(Arg1);
  627.             r1 = d;
  628.             }
  629. #else                    /* WATERLOO_C_V3_0 */
  630.             r1 = IntVal(Arg1);
  631. #endif                    /* WATERLOO_C_V3_0 */
  632.          }
  633.       else
  634.      r1 = BlkLoc(Arg1)->realblk.realval;
  635.  
  636.       if (t2 != T_Real) {
  637.  
  638. #ifdef LargeInts
  639.      if (t2 == T_Bignum)
  640.         r2 = bigtoreal(&Arg2);
  641.      else
  642. #endif                    /* LargeInts */
  643.  
  644. #ifdef WATERLOO_C_V3_0
  645.             {
  646.         long int l;
  647.             double d;
  648.  
  649.             d = IntVal(Arg2);
  650.             r2 = d;
  651.             }
  652. #else                    /* WATERLOO_C_V3_0 */
  653.             r2 = IntVal(Arg2);
  654. #endif                    /* WATERLOO_C_V3_0 */
  655.          }
  656.       else
  657.      r2 = BlkLoc(Arg2)->realblk.realval;
  658.  
  659.       if (makereal(r1 + r2, &Arg0) == Error) 
  660.          RunErr(0, NULL);
  661.       }
  662.  
  663. #ifdef LargeInts
  664.    else {
  665.       /*
  666.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  667.        */
  668.       if (bigadd(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  669.      RunErr(0, NULL);
  670.       }
  671. #endif                    /* LargeInts */
  672.  
  673.    Return;
  674.    }
  675.  
  676. /*
  677.  * x ^ y - raise x to the y power.
  678.  */
  679.  
  680. #if AMIGA
  681. #if AZTEC_C
  682. #ifndef RTACIS
  683. #define RTACIS
  684. #define AZTECHACK
  685. #endif                    /* RTACIS */
  686. #endif                    /* AZTEC_C */
  687. #endif                    /* AMIGA */
  688.  
  689. OpDcl(powr,2,"^")
  690.    {
  691.    register int t1, t2;
  692.    double r1, r2;
  693.  
  694.    /*
  695.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  696.     *  use.
  697.     */
  698.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  699.       RunErr(102, &Arg1);
  700.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  701.       RunErr(102, &Arg2);
  702.  
  703.    if (t1 == T_Integer && t2 == T_Integer) {
  704.       /*
  705.        * Both Arg1 and Arg2 are integers.  Perform integer exponentiation
  706.        *  and place the result in Arg0 as the return value.
  707.        */
  708.  
  709. #ifdef LargeInts
  710.       if (bigpow(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  711.      RunErr(0, NULL);
  712. #else                    /* LargeInts */
  713.       MakeInt(ipow(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  714.       if (over_flow)
  715.          RunErr(-203, NULL);
  716. #endif                    /* LargeInts */
  717.  
  718.       }
  719.    else if (t1 == T_Real || t2 == T_Real) {
  720.       /*
  721.        * Either x or y is real, convert the other to a real, perform
  722.        *  real exponentiation and place the result in Arg0 as the
  723.        *  return value.
  724.        */
  725.       if (t1 != T_Real) {
  726.  
  727. #ifdef LargeInts
  728.      if (t1 == T_Bignum)
  729.         r1 = bigtoreal(&Arg1);
  730.      else
  731. #endif                    /* LargeInts */
  732.  
  733. #ifdef WATERLOO_C_V3_0
  734.             {
  735.         long int l;
  736.             double d;
  737.  
  738.             d = IntVal(Arg1);
  739.             r1 = d;
  740.             }
  741. #else                    /* WATERLOO_C_V3_0 */
  742.             r1 = IntVal(Arg1);
  743. #endif                    /* WATERLOO_C_V3_0 */
  744.          }
  745.       else
  746.      r1 = BlkLoc(Arg1)->realblk.realval;
  747.  
  748.       if (t2 != T_Real) {
  749.  
  750. #ifdef LargeInts
  751.      if (t2 == T_Bignum)
  752.         r2 = bigtoreal(&Arg2);
  753.      else
  754. #endif                    /* LargeInts */
  755.  
  756. #ifdef WATERLOO_C_V3_0
  757.             {
  758.         long int l;
  759.             double d;
  760.  
  761.             d = IntVal(Arg2);
  762.             r2 = d;
  763.             }
  764. #else                    /* WATERLOO_C_V3_0 */
  765.             r2 = IntVal(Arg2);
  766. #endif                    /* WATERLOO_C_V3_0 */
  767.          }
  768.       else
  769.      r2 = BlkLoc(Arg2)->realblk.realval;
  770.  
  771.       if (r1 == 0.0 && r2 <= 0.0) 
  772.          /*
  773.           * Tried to raise zero to a negative power.
  774.           */
  775.          RunErr(-204, NULL);
  776.       if (r1 < 0.0 && t2 == T_Real) 
  777.          /*
  778.           * Tried to raise a negative number to a real power.
  779.           */
  780.          RunErr(-206, NULL);
  781.  
  782. #ifdef RTACIS
  783.       {
  784.        double rtbug_temporary;        /* bug in pow routine for negative x */
  785.  
  786.        if ((r1 < 0.0) && /* integral? */ (((double)((long int)r2)) == rs)) {
  787.           rtbug_temporary = -r1; 
  788.  
  789.           /*
  790.            * The following is correct only if the exponent is odd.
  791.            *  If the exponent is even, it should be
  792.            *
  793.            *      pow(-rtbug_temporary,r2);
  794.            *
  795.            */
  796.           rtbug_temporary = -pow(rtbug_temporary, r2); 
  797.           } 
  798.        else
  799.       rtbug_temporary = pow(r1, r2);
  800.        if (makereal(rtbug_temporary, &Arg0) == Error) 
  801.           RunErr(0, NULL);
  802.       }
  803. #else                    /* RTACIS */
  804.       if (makereal(pow(r1, r2), &Arg0) == Error) 
  805.          RunErr(0, NULL);
  806. #endif                    /* RTACIS */
  807.       }
  808.  
  809. #ifdef LargeInts
  810.    else {
  811.       /*
  812.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  813.        */
  814.       if (bigpow(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  815.      RunErr(0, NULL);
  816.       }
  817. #endif                    /* LargeInts */
  818.  
  819.    Return;
  820.    }
  821.  
  822. #if AMIGA
  823. #if AZTEC_C
  824. #ifdef AZTECHACK
  825. #undef RTACIS
  826. #endif                    /* AZTECHACK */
  827. #endif                    /* AZTEC_C */
  828. #endif                    /* AMIGA */
  829.  
  830. #ifndef LargeInts
  831. long ipow(n1, n2)
  832. long n1, n2;
  833.    {
  834.    long result;
  835.  
  836.    if (n1 == 0 && n2 <= 0) {
  837.       over_flow = 1;
  838.       return 0;
  839.       }
  840.    if (n2 < 0)
  841.       return 0;
  842.    result = 1L;
  843.    while (n2 > 0) {
  844.       if (n2 & 01L)
  845.          result *= n1;
  846.       n1 *= n1;
  847.       n2 >>= 1;
  848.       }
  849.    over_flow = 0;
  850.    return result;
  851.    }
  852. #endif                    /* LargeInts */
  853.